package com.zmn.oms.task.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.manager.mq.annotation.AliyunMQHandler;
import com.zmn.manager.mq.annotation.AliyunMQListener;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.manager.utils.OmsMqTagConsts;
import com.zmn.oms.model.dto.remark.OrderRemarkDetailDTO;
import com.zmn.oms.model.dto.work.modify.must.CancelApplyDTO;
import com.zmn.oms.model.dto.work.modify.must.ZsCancelDTO;
import com.zmn.oms.model.entity.masterworking.MasterWorking;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.masterworking.MasterWorkingService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.normal.business.interfaces.work.ZsNormalWorkBService;
import com.zmn.track.common.constant.apply.cancel.CancelApplyConsts;
import com.zmn.track.dubbo.dio.apply.cancel.CheckAllowApplyCancelDIO;
import com.zmn.track.dubbo.dio.apply.cancel.SubmitApplyCancelDIO;
import com.zmn.track.dubbo.dro.apply.cancel.CheckAllowApplyCancelDRO;
import com.zmn.track.dubbo.interfaces.apply.cancel.OrderCancelApplyListRemoteService;
import com.zmn.track.dubbo.interfaces.apply.cancel.OrderCancelApplyModifyRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * @author ligang
 * @date:2021/10/27 3:51 下午
 * description:
 */
@Slf4j
@Component
@AliyunMQListener(topic = "${spring.mq.topic.oms}")
public class OrderCancelListener {

    @Autowired
    private MasterWorkingService masterWorkingService;
    @Autowired
    private ZsNormalWorkBService zsNormalWorkBService;
    @Autowired
    private OrderWorkService orderWorkService;

    @Reference(version = com.zmn.track.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private OrderCancelApplyListRemoteService orderCancelApplyListRemoteService;
    @Reference(version = com.zmn.track.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private OrderCancelApplyModifyRemoteService orderCancelApplyModifyRemoteService;

    @NacosValue(value = "${order.unable.service.cancel.reason.id:21}", autoRefreshed = true)
    private Integer cancelReasonId;


    /**
     * 用户取消，工程师超时未处理，自动取消订单
     *
     * @param message
     */
    // @AliyunMQHandler(tags = OmsMqTagConsts.ZMN_TOPIC_OMS_ENGINEER_REVIEW_CANCEL_CHECK)
    public void engineerReviewCancelCheck(String message) {
        try {
            CancelApplyDTO cancelApplyDTO = JSON.parseObject(message, CancelApplyDTO.class);
            log.info("OrderCancelListener.engineerCancelCheck入参  workId={}", cancelApplyDTO.getWorkId());
            MasterWorking masterWorking = masterWorkingService.findMasterWorkingByWorkId(cancelApplyDTO.getWorkId());
            if (Objects.isNull(masterWorking)) {
                log.info("没有查询到工程师进行中的订单：workId={}", cancelApplyDTO.getWorkId());
                return;
            }

            if (Objects.equals(masterWorking.getWaitCancel(), GlobalConsts.NO)) {
                log.info("工程师审核取消检查，跟单已处理：workId={}", cancelApplyDTO.getWorkId());
                return;
            }
            log.info("工程师审核取消检查，工程师未处理系统自动取消：workId={}", cancelApplyDTO.getWorkId());

            // 未处理系统自动取消
            Optional<OrderRemarkDetailDTO> orderRemarkDetail = cancelApplyDTO.getDetailDTOList().stream().findFirst();
            if (!orderRemarkDetail.isPresent()) {
                log.info("工程师审核取消检查，工程师未处理系统自动取消时无取消缘由：workId={}", cancelApplyDTO.getWorkId());
                return;
            }
            ZsCancelDTO zsCancelDTO = new ZsCancelDTO();
            zsCancelDTO.setOrderId(cancelApplyDTO.getOrderId());
            zsCancelDTO.setWorkId(cancelApplyDTO.getWorkId());
            List<OrderRemarkDetailDTO> detailDTOList = Lists.newArrayList();
            OrderRemarkDetailDTO dto = new OrderRemarkDetailDTO();
            dto.setMapId(orderRemarkDetail.get().getMapId());
            dto.setMapName(orderRemarkDetail.get().getMapName());
            detailDTOList.add(dto);
            zsCancelDTO.setDetailDTOList(detailDTOList);

            // 操作人信息
            zsCancelDTO.setOperator(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
            zsCancelDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
            zsCancelDTO.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
            zsCancelDTO.setOperatorLogRemark("工程师未处理，系统自动取消");

            log.info("用户取消申请处理超时，系统自动取消 入参：{}", JSON.toJSONString(zsCancelDTO));
            zsNormalWorkBService.saveCancel(zsCancelDTO);



        } catch (Exception e) {
            log.error("用户取消申请处理超时，系统自动取消失败：{}", message, e);
        }
    }

    /**
     * 订单收单操作
     *
     * @param message
     */
    @AliyunMQHandler(tags = OmsMqTagConsts.ORDER_WORK_JXJ_DELAYED_CANCEL_TAG)
    public void jxjDelayedCancel(String message) {
        log.debug("#OrderCancelListener#jxjDelayedCancel message:[{}]", message);
        try {
            JSONObject jsonObject = JSON.parseObject(message);
            if (Objects.isNull(jsonObject)) {
                return;
            }
            OrderWork orderWork = orderWorkService.findOrderWorkByKey(jsonObject.getLong("orderId"), jsonObject.getLong("workId"));
            // 不在进行中
            if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
                return;
            }
            // 已派单直接返回
            if (NumberUtil.isNotNullOrZero(orderWork.getMasterId())) {
                return;
            }

            // 是否真实取消
            boolean isRealCancel = true;

            // 判断是否允许申请
            CheckAllowApplyCancelDIO applyCancelDIO = CheckAllowApplyCancelDIO
                    .builder()
                    .orderId(orderWork.getOrderId())
                    .workId(orderWork.getWorkId())
                    .applySource(CancelApplyConsts.CANCEL_APPLY_SOURCE_SYS_AUTO)
                    .channelId(orderWork.getChannelId())
                    .cityId(orderWork.getCityId())
                    .channelId(orderWork.getChannelId())
                    .servCategId(orderWork.getServCategId())
                    .showCategId(orderWork.getShowCategId())
                    .build();
            log.info("{} 检查是否允许申请取消入参 applyCancelDIO={}", orderWork.getWorkId(), applyCancelDIO);
            ResponseDTO<CheckAllowApplyCancelDRO> checkAllowApplyCancelDROResponseDTO = orderCancelApplyListRemoteService.checkAllowApplyCancel(applyCancelDIO);
            log.info("{} 检查是否允许申请取消出参 checkAllowApplyCancelDROResponseDTO={}", orderWork.getWorkId(), checkAllowApplyCancelDROResponseDTO);
            if (!checkAllowApplyCancelDROResponseDTO.isSuccess() || Objects.isNull(checkAllowApplyCancelDROResponseDTO.getData())) {
                isRealCancel = false;
            }
            CheckAllowApplyCancelDRO dro = checkAllowApplyCancelDROResponseDTO.getData();
            if (dro.isAllowApply()) {
                isRealCancel = false;
            }

            if (isRealCancel) {
                ZsCancelDTO zsCancelDTO = new ZsCancelDTO();
                zsCancelDTO.setOrderId(orderWork.getOrderId());
                zsCancelDTO.setWorkId(orderWork.getWorkId());
                List<OrderRemarkDetailDTO> detailDTOList = Lists.newArrayList();
                OrderRemarkDetailDTO dto = new OrderRemarkDetailDTO();
                dto.setMapId(cancelReasonId);
                dto.setMapName("无法服务线索，系统取消工单");
                detailDTOList.add(dto);
                zsCancelDTO.setDetailDTOList(detailDTOList);

                // 操作人信息
                zsCancelDTO.setOperator(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
                zsCancelDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
                zsCancelDTO.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
                log.info("无法服务线索，系统取消工单 入参：{}", JSON.toJSONString(zsCancelDTO));
                zsNormalWorkBService.saveCancel(zsCancelDTO);
            }else {
                // 发起取消申请
                Map<Integer, String> reasonMap = Maps.newHashMap();
                reasonMap.put(cancelReasonId, "无法服务线索，系统取消工单");
                SubmitApplyCancelDIO submitApplyCancelDIO = SubmitApplyCancelDIO
                        .builder()
                        .orderId(orderWork.getOrderId())
                        .workId(orderWork.getWorkId())
                        .applySource(CancelApplyConsts.CANCEL_APPLY_SOURCE_SYS_AUTO)
                        .operator(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SYSTEM))
                        .operatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM)
                        .operatorType(GlobalConsts.OPERATE_USER_TYPE_SYSTEM)
                        .reasonMap(reasonMap)
                        .build();
                log.info("{} 提交取消申请#submitApplyCancel submitApplyCancelDIO={}", orderWork.getWorkId(), submitApplyCancelDIO);
                ResponseDTO responseDTO = orderCancelApplyModifyRemoteService.submitApplyCancel(submitApplyCancelDIO);
                log.info("{} 提交取消申请#submitApplyCancel responseDTO={}", orderWork.getWorkId(), responseDTO);
            }
        } catch (Exception e) {
            log.error("#oms#OrderCancelListener#jxjDelayedCancel {}", e.getMessage(), e);
            e.printStackTrace();
        }
    }
}
